# server net/irc.py

import asyncore
import logging
import socket
import string
from tools import config
import traceback
import time

BUF = 2048

nodes = []

logging.basicConfig (level = logging.DEBUG, format = "%(created)-15s %(msecs)d %(levelname)8s %(thread)d %(name)s %(message)s")
log = logging.getLogger (__name__)


class Conn(asyncore.dispatcher):
	"IRC connection class"
	
	def __init__ (self, node, parser):
		"""initial stuff"""
		asyncore.dispatcher.__init__ (self)
		self.debug = config.getDebug ()
		if self.debug :
			log.debug ("__init__")
		self.is_alive = False
		self.port = node[2]
		self.nick = config.getServerID ()
		self.addr = node[1]
		self.nodes = []
		for n in config.getNodeList () :
			if n[2] == self.port and n[1] == self.addr :
				self.nodes.append (n[0])
		self.parser = parser
		self.write_to = ""
		self.ready_to_send = False
		self.new_msg = True
		self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
		self.connect ((self.addr, self.port))
	
	def handle_read (self) :
		""" """
		global nodes
		if self.debug :
			log.debug ("handle_read")
		data_in = self.recv (BUF)
		if self.debug :
			log.debug ("after recv")
		if data_in :
			if self.debug :
				log.debug ("got data")
			msgs = list( string.split (data_in, "\r\n"))
			for msg in msgs:
				m = tuple (string.split (msg, " "))
				if len(m) > 1 and len(m[0]) > 0 :
					if m[0] == "PING" :
						self.send ("PONG %s\r\n" + m[1])
					elif m[1] == "PRIVMSG" and len(m) > 3 :
						nick = string.split(m[0][1:], "!")[0]
						mm = m[3][1:]
						mm += " " + string.join (m[4:], " ")
						self.parser.parsemsg (mm, self, nick)
					elif m[1] == "353" and len(m) > 5 :
						if m[4][1:] in string.split (string.join (m[5:], \
						" ")[1:], " ") :
							if m[4][1:] in nodes :
								self.send ("PRIVMSG %s :re %s\r\n" % (m[4], \
								config.getServerID ()))
							else :
								nodes.append (m[4][1:])
								self.send ("PRIVMSG %s :hi %s\r\n" % (m[4], \
								config.getServerID ()))
		else :
			if self.debug :
				log.debug ("no data")
	
	def handle_write(self):
		if self.debug :
			log.debug ("handle_write")
		if self.data_out :
			if self.new_msg :
				self.data_out = "PRIVMSG #%s :" % self.write_to  + self.data_out
				self.new_msg = False
			sent = self.send (self.data_out)
			if self.debug :
				log.debug ("data sent")
			self.data_out = self.data_out[sent:]
		else :
			if self.debug :
				log.debug ("nothing to send")
		if len (self.data_out) == 0:
			self.ready_to_send = False
			self.new_msg = True
			self.write_to = ""
	
	def handle_close (self):
		if self.debug :
			log.debug ("handle_close")
		self.is_alive = False
		self.close ()
		time.sleep (30)
		self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
		self.connect ((self.addr, self.port))
	
	def readable (self):
		return True
	
	def writable (self):
		return self.ready_to_send & len (self.write_to) > 0
	
	def handle_connect (self) :
		if self.debug :
			log.debug ("handle_connect")
		self.send ("NICK %s\r\n" %self.nick)
		self.send ("USER %s %s bla : %s\r\n" % (self.nick, self.addr, self.nick))
		for n in self.nodes :
			self.send("JOIN #%s\r\n" % n)
		self.is_alive = True
	
	def handle_error (self) :
		if self.debug :
			log.debug ("handle_error")
			traceback.print_exc ()
		self.is_alive = False
		self.close ()
		time.sleep (30)
		self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
		self.connect ((self.addr, self.port))

	def send_msg (self, data, to) :
		self.write_to = to
		self.data_out = data
		self.ready_to_send = True
